// 1,布尔类型
let bool: boolean;
bool = true;

// 2,数值类型
let num: number = 12;

// 2.1,各个进制
num = 0b1001001;
num = 0o174;
num = 0x123;

// 3,字符串
let str: string = '123';
str = `${num}`;

// 4,数组
let arr1: number[];
arr1 = [1, 2, 3, 4];
// 4.1,写法2
let arr2: Array<number>;

// 4.2,内容可以是 混合的
let arr3: (string | number)[];
arr3 = [1, 2, 3, 4, '1'];

// 4.3,只要里面有 {} 那么就是 {}[]
// attention: 里面有函数没事, 但是下面 貌似有问题？？？？？？
let arr4 = [
  () => {},
  () => {
    return 123;
  },
  1,
];

// 5,元组类型
// attention: 版本2.6之前越界元素 是 指定 的类型的任意一种就行，2.6 之后不允许有越界元素。
let tuple: [string, number, boolean];
tuple = ['1', 1, true];

// 6,枚举类型
// attention: 名字尽量大些
enum Roles {
  SUPER_ADMIN = 1,
  USER,
}
console.log(Roles.SUPER_ADMIN);

// 7,any类型
// attentions: 能不用就不要用
let value: any;
value = 123;
value = 'python';
value = [];
value = {};
value = new RegExp(/23/);

// 8,void：什么类型都不是
// attentions: 后期可以配置 使得 行参 不需要指定类型，也不会报错
const consoleText = (text: string): void => {
  console.log(text);
};
consoleText('123');

// 8.1 undefined 和 null 可以赋值给 void 类型的变量
let v: void;
v = undefined; // 不需要配置
//  v = null;  // 需要配置

// 8.2 undefined & null
let u: undefined;
u = undefined;

let n: null;
n = null;

// attention: undefined & null 是其他类型的子类型, 但是需要修改配置
// arr1 = undefined
// arr1 = null

// 9. never 类型
// attention: never 也是 其他类型的子类型,貌似也要配置
const errFunc = (message: string): never => {
  throw new Error();
};
const infiniteFunc = () => {
  while (1) {}
};

// 10, object
let obj = {
  name: 'pyhton',
};

function getObj(obj: object) {
  console.log(obj);
}

// 11, 类型断言
// attention:用于ts检查不了或检查错误的时候，经常在 联合类型上发生
// const getLength = (target: number | string) => {
//   if (target.length || target.length === 0) {
//     return target.length;
//   } else {
//     return target.toString.length;
//   }
// };

// 断言的写法如下
// 解决方法： 看下面2种方式
const getLength = (target: number | string) => {
  if ((<string>target).length || (target as string).length === 0) {
    return (<string>target).length;
  } else {
    return target.toString.length;
  }
};

// notice:
// 最优解
// 后面的 自定义类型保护 就不用上面的写法
// Jsx 只能 用 as 的写法：因为 <string> 像是一个标签
